home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Scope
/
Scope Disk #157 (199x)(Scope PD)(US)[WB].zip
/
Scope Disk #157 (199x)(Scope PD)(US)[WB].adf
/
LockDevice
/
LockDevice.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-25
|
13KB
|
641 lines
/* $Revision Header * Header built automatically - do not edit! *************
*
* (C) Copyright 1990 by MXM
*
* Name .....: LockDevice-Handler.c
* Created ..: Tuesday 26-Jun-90 14:19
* Revision .: 1
*
* Date Author Comment
* ========= ======== ====================
* 26-Jun-90 Olsen Created this file!
*
* $Revision Header ********************************************************/
/* Arp cli arguments. */
char *CLI_Template = "Drive,L=Lock/K,K=Key/K,S=Show/S,Info/S,Q=Quit/S";
char *CLI_Help = "\nUsage: LockDevice <DH0:, DH1:, etc.> [Lock <On|Off>]\n [Key <Password>] [Show] [Info] [Quit]\n";
/* Argument vector offsets. */
#define ARG_DRIVE 1
#define ARG_LOCK 2
#define ARG_KEY 3
#define ARG_SHOW 4
#define ARG_INFO 5
#define ARG_QUIT 6
/* Global lock segment. */
struct LockSeg *LSeg;
/* Prototypes. */
char * FindDevice(char *DevName);
struct Patch * FindPatch(char *DeviceName);
VOID DiskChange(char *DeviceName);
BYTE DeletePatch(char *DeviceName);
BYTE DeleteLocks(VOID);
BYTE DeleteSegment(VOID);
BYTE CreateSegment(VOID);
VOID main(int argc,char **argv);
/* FindDevice(char *DevName):
*
* Find the device(s) associated with a device
* driver.
*/
char *
FindDevice(char *DevName)
{
static char Name[257];
static struct DeviceNode *DevInfo = NULL;
static BYTE FirstThrough = TRUE;
Forbid();
if(!DevInfo)
{
DevInfo = (struct DeviceNode *)BADDR(((struct DosInfo *)BADDR(((struct RootNode *)DOSBase -> dl_Root) -> rn_Info)) -> di_DevInfo);
if(!FirstThrough)
return(NULL);
else
FirstThrough = FALSE;
}
while(DevInfo)
{
if(DevInfo -> dn_Type == DLT_DEVICE && DevInfo -> dn_Task && !DevInfo -> dn_Handler)
{
struct FileSysStartupMsg *Startup = BADDR(DevInfo -> dn_Startup);
if(!Strcmp((char *)((ULONG)BADDR(Startup -> fssm_Device) + 1),DevName))
{
char *Pointer;
SHORT i;
Pointer = (char *)BADDR(DevInfo -> dn_Name);
for(i = 0 ; i < Pointer[0] ; i++)
Name[i] = Pointer[i + 1];
Name[Pointer[0] ] = ':';
Name[Pointer[0] + 1] = 0;
DevInfo = (struct DeviceNode *)BADDR(DevInfo -> dn_Next);
Permit();
return(Name);
}
}
DevInfo = (struct DeviceNode *)BADDR(DevInfo -> dn_Next);
}
Permit();
return(NULL);
}
/* FindDriver(char *DevName):
*
* Find the device driver associated with a filing device.
*/
char *
FindDriver(char *DevName)
{
static char Name[257];
struct DeviceNode *DevInfo = (struct DeviceNode *)BADDR(((struct DosInfo *)BADDR(((struct RootNode *)DOSBase -> dl_Root) -> rn_Info)) -> di_DevInfo);
Forbid();
while(DevInfo)
{
char *Pointer;
SHORT i;
Pointer = (char *)BADDR(DevInfo -> dn_Name);
for(i = 0 ; i < Pointer[0] ; i++)
Name[i] = Pointer[i + 1];
Name[Pointer[0] ] = ':';
Name[Pointer[0] + 1] = 0;
if(DevInfo -> dn_Type == DLT_DEVICE && DevInfo -> dn_Task && !DevInfo -> dn_Handler)
{
if(!Strcmp(Name,DevName))
{
struct FileSysStartupMsg *Startup = BADDR(DevInfo -> dn_Startup);
strcpy(Name,(char *)((ULONG)BADDR(Startup -> fssm_Device) + 1));
DevInfo = (struct DeviceNode *)BADDR(DevInfo -> dn_Next);
Permit();
return(Name);
}
}
DevInfo = (struct DeviceNode *)BADDR(DevInfo -> dn_Next);
}
Permit();
return(NULL);
}
/* FindPatch(char *DeviceName):
*
* Find the patch created for a specific filing device.
*/
struct Patch *
FindPatch(char *DeviceName)
{
struct Patch *Patch = LSeg -> RootPatch;
while(Patch)
{
if(!Strcmp(Patch -> UnitName,DeviceName))
return(Patch);
Patch = Patch -> NextPatch;
}
return(NULL);
}
/* DiskChange(char *DeviceName):
*
* Perform a kind of diskchange event for a filing
* device.
*/
VOID
DiskChange(char *DeviceName)
{
struct MsgPort *HandlerTask = DeviceProc(DeviceName);
LONG Args[7];
if(HandlerTask)
{
Args[0] = DOSTRUE;
if(SendPacket(ACTION_INHIBIT,Args,HandlerTask))
{
Args[0] = DOSFALSE;
SendPacket(ACTION_INHIBIT,Args,HandlerTask);
}
}
}
/* DeletePatch(char *DeviceName):
*
* Unlink and remove a patch from the linked system
* list.
*/
BYTE
DeletePatch(char *DeviceName)
{
if(DeviceName)
{
struct Patch *TempPatch = LSeg -> RootPatch,*OldPatch = NULL;
Disable();
if(!Strcmp(TempPatch -> UnitName,DeviceName))
{
OldPatch = TempPatch;
LSeg -> RootPatch = TempPatch -> NextPatch;
}
else
{
while(TempPatch)
{
if(!Strcmp(TempPatch -> UnitName,DeviceName))
{
OldPatch = TempPatch;
break;
}
TempPatch = TempPatch -> NextPatch;
}
if(!OldPatch)
return(FALSE);
else
{
TempPatch = LSeg -> RootPatch;
while(TempPatch)
{
if(TempPatch -> NextPatch == OldPatch)
{
TempPatch -> NextPatch = OldPatch -> NextPatch;
break;
}
TempPatch = TempPatch -> NextPatch;
}
}
}
SetFunction((struct Library *)OldPatch -> Device,DEV_BEGINIO,OldPatch -> OldBeginIO);
Enable();
CloseDevice(OldPatch -> Request);
FreeMem(OldPatch -> Request,sizeof(struct IOExtTD));
FreeMem(OldPatch,sizeof(struct Patch));
DiskChange(DeviceName);
return(TRUE);
}
return(FALSE);
}
/* DeleteLocks():
*
* Delete all patches which are not protected by a
* password.
*/
BYTE
DeleteLocks()
{
struct Patch *Patch = LSeg -> RootPatch;
while(Patch)
{
if(!Patch -> PassWord[0])
{
DeletePatch(Patch -> UnitName);
Patch = LSeg -> RootPatch;
continue;
}
Patch = Patch -> NextPatch;
}
if(LSeg -> RootPatch)
return(FALSE);
else
return(TRUE);
}
/* DeleteSegment():
*
* Deallocate the lock segment.
*/
BYTE
DeleteSegment()
{
if(LSeg)
{
if(DeleteLocks())
{
LSeg -> HandShake = SIG_SHAKE;
Signal(LSeg -> Child,SIG_QUIT);
Wait(SIG_SHAKE);
if(!LSeg -> Child)
{
RemPort(&LSeg -> SignalPort);
FreeMem(LSeg -> SignalPort . mp_Node . ln_Name,sizeof(PORTNAME));
UnLoadSeg(LSeg -> HandlerSegment);
FreeMem(LSeg,sizeof(struct LockSeg));
return(TRUE);
}
}
}
return(FALSE);
}
/* CreateSegment():
*
* Create the lock segment.
*/
BYTE
CreateSegment()
{
if(LSeg = (struct LockSeg *)AllocMem(sizeof(struct LockSeg),MEMF_PUBLIC | MEMF_CLEAR))
{
LSeg -> SegSize = sizeof(struct LockSeg);
LSeg -> Father = SysBase -> ThisTask;
LSeg -> SignalPort . mp_Node . ln_Type = NT_MSGPORT;
LSeg -> SignalPort . mp_Node . ln_Pri = 1;
LSeg -> SignalPort . mp_Node . ln_Name = (char *)AllocMem(sizeof(PORTNAME),MEMF_PUBLIC);
LSeg -> SignalPort . mp_Flags = PA_IGNORE;
if(LSeg -> SignalPort . mp_Node . ln_Name)
{
strcpy(LSeg -> SignalPort . mp_Node . ln_Name,PORTNAME);
if(!(LSeg -> HandlerSegment = LoadSeg("LockDevice-Handler")))
LSeg -> HandlerSegment = LoadSeg("L:LockDevice-Handler");
if(LSeg -> HandlerSegment)
{
LSeg -> HandShake = SIG_SHAKE;
AddPort(&LSeg -> SignalPort);
if(CreateProc(PORTNAME,5,LSeg -> HandlerSegment,4000))
{
Wait(SIG_SHAKE);
if(LSeg -> Child)
return(TRUE);
}
RemPort(&LSeg -> SignalPort);
UnLoadSeg(LSeg -> HandlerSegment);
}
FreeMem(LSeg -> SignalPort . mp_Node . ln_Name,sizeof(PORTNAME));
}
FreeMem(LSeg,sizeof(struct LockSeg));
}
return(FALSE);
}
/* main(int argc,char **argv):
*
* The main program.
*/
VOID
main(int argc,char **argv)
{
LSeg = (struct LockSeg *)FindPort(PORTNAME);
if(argc == 1)
{
Puts(CLI_Help);
exit(RETURN_WARN);
}
/* Remove LockDevice? */
if(argv[ARG_QUIT])
{
Printf("\nRemoving \33[33mLockDevice\33[31m, ");
if(!DeleteSegment())
{
Puts("FAILED!\a\n");
exit(RETURN_FAIL);
}
else
{
Puts("\33[3mOkay.\33[0m\n");
exit(RETURN_OK);
}
}
/* Show program info? */
if(argv[ARG_INFO])
{
Puts("This program installs patches to prevent write access to");
Puts("data media. Unlike the write protection simulated by the");
Puts("FastFileSystem, 'LockDevice' goes directly to the device");
Puts("driver itself which enables it to reject write/format");
Puts("requests even in situations in which FastFileSystem fails");
Puts("and the disk drive is still formatted.");
Puts(" Furthermore, 'LockDevice' will work on any device and");
Puts("with any filing system.\n");
Puts("If you like this program and use it frequently, send a");
Puts("Share-Ware fee of at least 15 US$ or DM 20,- to:\n");
Puts(" Olaf Barthel, MXM");
Puts(" Brabeckstrasse 35");
Puts(" D-3000 Hannover 71\n");
Puts(" Federal Republic of Germany\n");
Puts("If you fail to pay this fee, then your conscience will haunt");
Puts("you for the rest of your life!\n");
exit(RETURN_OK);
}
/* Install the lock segment. */
if(!LSeg)
{
Printf("\nInstalling \33[33m\33[1mLockDevice\33[31m\33[0m, ");
if(!CreateSegment())
{
Puts("FAILED!\n\a");
exit(RETURN_FAIL);
}
else
Printf("\33[3mOkay.\33[0m v1.%ld © Copyright 1990 by \33[4mMXM\33[0m, \33[1mSHARE-WARE\33[0m.\n\n",REVISION);
}
/* Install/remove a patch. */
if(argv[ARG_DRIVE])
{
/* Remove a patch. */
if(!Strcmp(argv[ARG_LOCK],"OFF"))
{
struct Patch *Patch;
if(!(Patch = FindPatch(argv[ARG_DRIVE])))
{
Printf("\33[1mLockDevice:\33[0m Unable to find locked device '%s'.\a\n",argv[ARG_DRIVE]);
exit(RETURN_FAIL);
}
/* Protected by a password? */
if(Patch -> PassWord[0])
{
/* Password given? */
if(argv[ARG_KEY])
{
/* Does it match? */
if(Strcmp(argv[ARG_KEY],(char *)Patch -> PassWord))
{
Printf("\33[1mLockDevice:\33[0m Invalid access key for locked device '%s'.\a\n",argv[ARG_DRIVE]);
exit(RETURN_FAIL);
}
else
{
DeletePatch(argv[ARG_DRIVE]);
Printf("\33[1mLockDevice:\33[0m Device '%s' unlocked.\n",argv[ARG_DRIVE]);
}
}
else
{
Printf("\33[1mLockDevice:\33[0m Device '%s' needs a key to be unlocked.\a\n",argv[ARG_DRIVE]);
exit(RETURN_FAIL);
}
}
else
{
DeletePatch(argv[ARG_DRIVE]);
Printf("\33[1mLockDevice:\33[0m Device '%s' unlocked.\n",argv[ARG_DRIVE]);
}
}
else
{
/* Lock a device. */
if(!Strcmp(argv[ARG_LOCK],"ON"))
{
struct LockMsg Message;
char *LockOut[40],*Pointer,*DevName;
SHORT NumLocked = 0;
if(!(DevName = FindDriver(argv[ARG_DRIVE])))
{
Printf("\33[1mLockDevice:\33[0m Unable to find driver for device '%s'!\a\n",argv[ARG_DRIVE]);
exit(RETURN_FAIL);
}
/* Look how many filing devices this lock will affect. */
while(Pointer = FindDevice(DevName))
{
if(!(LockOut[NumLocked] = ArpAlloc(strlen(Pointer) + 1)))
{
Printf("\33[1mLockDevice:\33[0m Out of memory!\a\n");
exit(RETURN_FAIL);
}
strcpy(LockOut[NumLocked++],Pointer);
if(NumLocked == 40)
break;
}
/* More than one device locked out? */
if(NumLocked > 1)
{
SHORT i;
char Line[MaxInputBuf];
Printf("\33[33mWarning:\33[31m Locking '%s' will also lock the following device(s):\n\n\t\33[1m",argv[ARG_DRIVE]);
for(i = 0 ; i < NumLocked ; i++)
if(Strcmp(LockOut[i],argv[ARG_DRIVE]))
Printf("%s ",LockOut[i]);
Printf("\n\n\33[0mDo you wish to continue (\33[33my\33[31m/\33[33mN\33[31m) ? ");
ReadLine(Line);
if(Line[0] != 'y' && Line[0] != 'Y')
exit(RETURN_WARN);
}
Message . ExecMessage . mn_Node . ln_Type = NT_MESSAGE;
Message . ExecMessage . mn_Length = sizeof(struct LockMsg);
Message . Success = FALSE;
/* Ask the handler to lock the device(s). */
if(Message . ExecMessage . mn_ReplyPort = (struct MsgPort *)CreatePort(NULL,0))
{
Message . DeviceName = argv[ARG_DRIVE];
Message . PassWord = argv[ARG_KEY];
PutMsg(&LSeg -> SignalPort,&Message);
WaitPort(Message . ExecMessage . mn_ReplyPort);
GetMsg(Message . ExecMessage . mn_ReplyPort);
DeletePort(Message . ExecMessage . mn_ReplyPort);
}
if(!Message . Success)
{
Printf("\33[1mLockDevice:\33[0m Could not create lock for device '%s'.\a\n",argv[ARG_DRIVE]);
exit(RETURN_FAIL);
}
else
{
Printf("\33[1mLockDevice:\33[0m Device '%s' locked.\n",argv[ARG_DRIVE]);
DiskChange(argv[ARG_DRIVE]);
}
}
else
{
Puts(CLI_Help);
exit(RETURN_FAIL);
}
}
}
/* Show all locked devices. */
if(argv[ARG_SHOW])
{
struct Patch *Patch = LSeg -> RootPatch;
if(!Patch)
{
Puts("\33[1mLockDevice:\33[0m There are no locked devices.");
exit(RETURN_WARN);
}
else
{
char *TempName;
Puts("Name Driver \n-------- --------------------");
while(Patch)
{
while(TempName = FindDevice(Patch -> DriverName))
{
if(!Strcmp(Patch -> UnitName,TempName))
Printf("\33[33m%-8.8s\33[31m %-20.20s\n",TempName,Patch -> DriverName);
else
Printf("%-8.8s %-20.20s\n",TempName,Patch -> DriverName);
}
Patch = Patch -> NextPatch;
}
}
}
exit(RETURN_OK);
}